#pragma once
#include <cmath>
#include <iostream>
#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/Service/Constraint/RBE2Service.h"
#include "DBManager/Service/DBServiceFactory.h"
#include "DataStructure/Common/include/Constant.h"
#include "DataStructure/FEM/Constraint/include/RBE2Data.h"

using SG::DataStructure::Common::PI;
using SG::DataStructure::Common::Real;
using SG::DataStructure::FEM::DOFDirections;
using SG::DataStructure::Common::Id;
using namespace SG::DBManager;
/** @brief 圆环模型， 测试RBE2单元计算
 *
 * 圆环被分成8段， 其中 4个节点和环中心的节点通过RBE2 单元相连接。
 */
class RBE2Load_Ring
{
  public:
    RBE2Load_Ring ()
        : m_dbServiceFactory (std::make_shared<DBServiceFactory> (*DataBaseFactory::GetDataBase (DataBaseFactory::HDF5, ".", "test.h5")))
    {
        m_dbServiceFactory->ClearDatabase ();
        Input (m_dbServiceFactory);
    }

    /// @brief 写入模型数据
    void               Input (const DBServiceFactorySP dbServiceFactory);
    DBServiceFactorySP GetModel ()
    {
        return m_dbServiceFactory;
    }

  private:
    DBServiceFactorySP m_dbServiceFactory;
};

void RBE2Load_Ring::Input (const DBServiceFactorySP dbServiceFactory)
{
    // 节点写入
    std::vector<Id>                  nodeIds{ 1, 2, 3, 13, 14, 21, 22, 30 };
    SG::DataStructure::FEM::NodeData node;
    Real                             r = 2.0;
    for (int index = 0; index < 8; ++index)
    {
        node.m_id   = nodeIds[index];
        auto theta  = 2.0 * PI * index / 8.0;
        node.m_x[0] = sin (theta) * r;
        node.m_x[1] = cos (theta) * r;
        dbServiceFactory->get<INodeService> ()->Add (node);
        std::cout << "cord" << node.m_x[0] << " " << node.m_x[1] << "\n";
    }

    // 中心节点
    node.m_id   = 5;
    node.m_x[0] = 0.0;
    node.m_x[1] = 0.0;
    dbServiceFactory->get<INodeService> ()->Add (node);

    // 圆周使用梁单元连接，用于激活自由度

    // 使用RBE2 约束 {1 3 14 22}节点
    {
        SG::DataStructure::FEM::RBE2Data rbe2;
        rbe2.m_id         = 5;
        rbe2.m_masterNode = 5;
        rbe2.m_slaveDOFs  = DofSet2Int ({ DOFDirections::DOF_Ux,
                                          DOFDirections::DOF_Uy,
                                          DOFDirections::DOF_Uz,
                                          DOFDirections::DOF_Rotx,
                                          DOFDirections::DOF_Roty,
                                          DOFDirections::DOF_Rotz });
        rbe2.m_slaveNodes = { 1, 3, 14, 22 };
        dbServiceFactory->get<RBE2Service> ()->Add (rbe2);
    }
    // 节点固定约束
    {
        SG::DataStructure::FEM::SPCData spc;
        spc.m_g = 2;
        spc.m_c = DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        spc.m_d = 0;
        dbServiceFactory->get<SPCService> ()->Add (spc);
        spc.m_g = 13;
        spc.m_c = DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        spc.m_d = 0;
        dbServiceFactory->get<SPCService> ()->Add (spc);
        spc.m_g = 21;
        spc.m_c = DofSet2Int ({ DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz });
        spc.m_d = 0;
        dbServiceFactory->get<SPCService> ()->Add (spc);
    }
}